﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace DriveBeamEditor.Wpf
{
    public static class SpiralCoords
    {
        public static IEnumerable<Tuple<int, int>> GenerateOutTo(int radius)
        {
            return Enumerable.Range(0, radius + 1).SelectMany(GenerateRing);
        }

        public static IEnumerable<Tuple<int, int>> GenerateRing(int radius)
        {
            var currentPoint = Tuple.Create(radius, 0);
            yield return Tuple.Create(currentPoint.Item1, currentPoint.Item2);

            //move up while we can
            while (currentPoint.Item2 < radius)
            {
                currentPoint = new Tuple<int, int>(currentPoint.Item1, currentPoint.Item2 + 1);
                yield return Tuple.Create(currentPoint.Item1, currentPoint.Item2);
            }
            //move left while we can
            while (-radius < currentPoint.Item1)
            {
                currentPoint = new Tuple<int, int>(currentPoint.Item1 - 1, currentPoint.Item2);
                yield return Tuple.Create(currentPoint.Item1, currentPoint.Item2);
            }
            //move down while we can
            while (-radius < currentPoint.Item2)
            {
                currentPoint = new Tuple<int, int>(currentPoint.Item1, currentPoint.Item2 - 1);
                yield return Tuple.Create(currentPoint.Item1, currentPoint.Item2);
            }
            //move right while we can
            while (currentPoint.Item1 < radius)
            {
                currentPoint = new Tuple<int, int>(currentPoint.Item1 + 1, currentPoint.Item2);
                yield return Tuple.Create(currentPoint.Item1, currentPoint.Item2);
            }
            //move up while we can
            while (currentPoint.Item2 < -1)
            {
                currentPoint = new Tuple<int, int>(currentPoint.Item1, currentPoint.Item2 + 1);
                yield return Tuple.Create(currentPoint.Item1, currentPoint.Item2);
            }
        }

    }
}
